package com.excilys.formation.project.entities;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;

import org.hibernate.annotations.Index;

/**
 * Operation est la classe de lien avec la table operation en base pour l'ORM.
 * 
 * @author excilys
 * 
 */
@Entity
public class Operation {
	/**
	 * Identifiant de l'objet.
	 */
	private long id;
	/**
	 * Montant de l'opération.
	 */
	private double montant;

	/**
	 * Type de l'opération.
	 */
	private TypeOperation type;

	/**
	 * Compte associé à l'opération.
	 */
	private Compte compte;

	/**
	 * Transaction associée.
	 */
	private Transaction transaction;

	/**
	 * Constructeur vide.
	 */
	public Operation() {

	}

	/**
	 * 
	 * @param montant
	 * @param type
	 * @param compte
	 * @param transaction
	 */
	public Operation(double montant, TypeOperation type, Compte compte, Transaction transaction) {
		super();
		this.montant = montant;
		this.type = type;
		this.compte = compte;
		this.transaction = transaction;
	}

	/**
	 * Renvoie l'identifiant de l'opération.
	 * 
	 * @return l'identifiant de l'opération
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	public long getId() {
		return id;
	}

	/**
	 * Change l'identifiant de l'opération.
	 * 
	 * @param id
	 *            le nouvel identifiant de l'opération.
	 */
	public void setId(long id) {
		this.id = id;
	}

	/**
	 * Renvoie le montant de l'opération.
	 * 
	 * @return le montant de l'opération
	 */
	@NotNull
	public double getMontant() {
		return montant;
	}

	/**
	 * Change le montant de l'opération.
	 * 
	 * @param montant
	 *            le nouveau montant de l'opération.
	 */
	public void setMontant(double montant) {
		this.montant = montant;
	}

	/**
	 * @return le type de transaction.
	 */
	@Index(name = "type")
	@NotNull
	@Enumerated(EnumType.STRING)
	public TypeOperation getType() {
		return type;
	}

	/**
	 * @param type
	 *            le nouveau le type de transaction.
	 */
	public void setType(TypeOperation type) {
		this.type = type;
	}

	/**
	 * @return Le compte associé à l'opération
	 */
	@ManyToOne(optional = false, fetch = FetchType.LAZY)
	public Compte getCompte() {
		return compte;
	}

	/**
	 * Change le compte de l'opération.
	 * 
	 * @param compte
	 *            Le nouveau compte de l'opération
	 */
	public void setCompte(Compte compte) {
		this.compte = compte;
	}

	/**
	 * 
	 * @return la transaction associée
	 */
	@ManyToOne(optional = false)
	public Transaction getTransaction() {
		return transaction;
	}

	/**
	 * Change la transaction associée.
	 * 
	 * @param transaction
	 *            la nouvelle transaction associée
	 */
	public void setTransaction(Transaction transaction) {
		this.transaction = transaction;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (id ^ (id >>> prime + result));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		Operation other = (Operation) obj;
		if (id != other.id) {
			return false;
		}
		return true;
	}

}
